/*
 * QApplicationDelegate.cpp  0.4.0 / Nov 17, 2010
 *
 * Copyright (c) 2010 - 2011, cute4j.com and contributors.
 *
 * This software is licensed under the LGPL version 2.1 license.
 * A copy of this license is included in the file LICENSE-LGPL.txt.
 */
#include "QApplicationDelegate.h"

// QApplicationDelegate :: Public Static Member Functions. ---------------------

/*!
 * \brief Initializes QApplicationDelegate class.
 *
 * \param env the JNIEnv pointer
 * \param args the command line arguments
 *
 * \exception FatalError if failed
 */
void QApplicationDelegate::initialize(JNIEnv *env, jobjectArray args)
{
  // TODO: clean
  Q_ASSERT(env);
  if (!qApplicationAdapter) {
    sm_argc = 1;
    if (args) {
      sm_argc = sm_argc + env->GetArrayLength(args);
    }
    sm_argv = (char **)calloc(sm_argc, sizeof(char *));
    if (!sm_argv) {
      FATAL_LOGGED_ERROR("QApplicationDelegate initialization failed");
    }
    sm_argv[0] = qstrdup("java");
    for (int i = 1; i < sm_argc; i++) {
      jstring jstr = (jstring)env->GetObjectArrayElement(args, i - 1);
      const char *str = env->GetStringUTFChars(jstr, 0);
      if (!str) {
        FATAL_LOGGED_ERROR("QApplicationDelegate initialization failed");
      }
      sm_argv[i] = qstrdup(str);
      env->ReleaseStringUTFChars(jstr, str);
      env->DeleteLocalRef(jstr);
    }
    static int argc = sm_argc;
    static char **argv = (char **)calloc(sm_argc, sizeof(char *));
    for (int i = 0; i < argc; i++) {
      argv[i] = qstrdup(sm_argv[i]);
    }
    qApplicationAdapter = new QApplicationAdapter(argc, argv);
    #ifndef CUTE4J_DEBUG
    QStringList libraryPaths = QApplicationAdapter::libraryPaths();
    for (int i = libraryPaths.size(); --i >= 0;) {
      QApplicationAdapter::removeLibraryPath(libraryPaths.at(i)); 
    }
    #endif // CUTE4J_DEBUG
    if (!qApplicationAdapter) {
      FATAL_LOGGED_ERROR("QApplicationDelegate initialization failed");
    }
  }
}

/*!
 * \brief Disposes application instance.
 */
void QApplicationDelegate::dispose()
{
  if (qApplicationAdapter) {
    qApplicationAdapter->processEvents();
    delete qApplicationAdapter;
    qApplicationAdapter = 0;
  }
}

/*!
 * \brief Returns keyboard modifiers.
 *
 * \return keyboard modifiers
 */
jint QApplicationDelegate::keyboardModifiers()
{
  jint modifiers = 0;
  Qt::KeyboardModifiers qModifiers = QApplication::keyboardModifiers();
  if (qModifiers & Qt::ShiftModifier) {
    modifiers |= 0x1;
  }
  if (qModifiers & Qt::ControlModifier) {
    modifiers |= 0x2;
  }
  if (qModifiers & Qt::MetaModifier) {
    modifiers |= 0x4;
  }
  if (qModifiers & Qt::AltModifier) {
    modifiers |= 0x8;
  }
  return modifiers;
}

/*!
 * \brief Returns mouse buttons.
 *
 * \return mouse buttons
 */
jint QApplicationDelegate::mouseButtons()
{
  jint buttons = 0;
  Qt::MouseButtons qButtons = QApplication::mouseButtons();
  if (qButtons & Qt::LeftButton) {
    buttons |= 0x10;
  }
  if (qButtons & Qt::RightButton) {
    buttons |= 0x20;
  }
  if (qButtons & Qt::MidButton) {
    buttons |= 0x40;
  }
  return buttons;
}

/*!
 * \brief Returns \c true if argv contains specified string.
 *
 * \param str the string
 *
 * \return \c true if argv contains specified string
 */
bool QApplicationDelegate::argvContains(const char *str)
{
  for (int i = 0; i < sm_argc; i++) {
    if (!qstricmp(sm_argv[i], str)) {
      return true;
    }
  }
  return false;
}

/*!
 * \brief Returns \c true if argv contains specified string.
 *
 * \param str the string
 * \param len the length
 *
 * \return \c true if argv contains specified string
 */
bool QApplicationDelegate::argvContains(const char *str, int len)
{
  for (int i = 0; i < sm_argc; i++) {
    if (!qstrnicmp(sm_argv[i], str, len)) {
      return true;
    }
  }
  return false;
}

// QApplicationDelegate :: Private Static Data Members. ------------------------

int QApplicationDelegate::sm_argc = 0;
char **QApplicationDelegate::sm_argv = 0;
QApplicationAdapter *QApplicationDelegate::qApplicationAdapter = 0;
